package com.vpx.server.service.system.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.vpx.server.bean.constant.HashMapSizeConstant;
import com.vpx.server.bean.order.base.BaseDeleteOrder;
import com.vpx.server.bean.order.base.BaseIdOrder;
import com.vpx.server.bean.order.system.SysRoleAuthOrder;
import com.vpx.server.bean.order.system.SysRoleOrder;
import com.vpx.server.bean.order.system.SysRolePageOrder;
import com.vpx.server.framework.aop.ServiceHandler;
import com.vpx.server.framework.base.ResultMsg;
import com.vpx.server.framework.exception.BizException;
import com.vpx.server.bean.entity.SysMenu;
import com.vpx.server.bean.entity.SysMenuOperate;
import com.vpx.server.bean.entity.SysRole;
import com.vpx.server.bean.entity.SysRoleAuth;
import com.vpx.server.bean.info.system.MenuOperateInfo;
import com.vpx.server.bean.info.system.RoleMenuOperateAuthInfo;
import com.vpx.server.mapper.system.*;
import com.vpx.server.bean.result.system.SysRoleMenuOperateAuthResult;
import com.vpx.server.bean.result.system.SysRolePageResult;
import com.vpx.server.bean.result.system.SysRoleResult;
import com.vpx.server.service.system.SysRoleService;
import com.vpx.server.framework.utils.DateUtils;
import com.vpx.server.utils.UserLoginUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liuks
 * @title: vpx
 * @module 角色管理
 * @description: 角色管理服务实现
 * @date 2021/9/9
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysMenuOperateMapper sysMenuOperateMapper;

    @Autowired
    private SysRoleAuthMapper sysRoleAuthMapper;

    @Autowired
    AuthorityMapper authorityMapper;

    @Override
    @ServiceHandler(memo = "新增角色", isTransaction = true)
    public ResultMsg insert(SysRoleOrder order) {
        SysRole sysRole = new SysRole();
        sysRole.from(order);
        sysRole.setCreateUserId(UserLoginUtils.getCurrentUser().getId());
        sysRole.setUpdateUserId(UserLoginUtils.getCurrentUser().getId());
        sysRole.setCreateTime(DateUtils.now());
        sysRole.setUpdateTime(DateUtils.now());
        sysRoleMapper.insert(sysRole);
        return new ResultMsg();
    }

    @Override
    @ServiceHandler(memo = "修改角色", isTransaction = true)
    public ResultMsg updateById(SysRoleOrder order) {
        SysRole role = sysRoleMapper.selectById(order.getId());
        if (role == null) {
            throw new BizException("未查询到角色信息");
        }
        role.from(order);
        role.setUpdateUserId(UserLoginUtils.getCurrentUser().getId());
        role.setUpdateTime(DateUtils.now());
        sysRoleMapper.updateById(role);
        return new ResultMsg();
    }

    @Override
    @ServiceHandler(memo = "删除角色", isTransaction = true)
    public ResultMsg deleteById(BaseDeleteOrder order) {
        sysRoleMapper.deleteById(order.getId());
        return new ResultMsg();
    }

    @Override
    @ServiceHandler(memo = "查询角色")
    public ResultMsg<SysRoleResult> findById(BaseIdOrder order) {
        SysRole role = sysRoleMapper.selectById(order.getId());
        if (role == null) {
            throw new BizException("未查询到角色信息");
        }
        SysRoleResult roleResult = new SysRoleResult();
        roleResult.from(role);

        List<Long> roleIdList = new ArrayList<Long>();
        roleIdList.add(role.getId());

        List<SysMenuOperate> operatorList = authorityMapper.queryAuthOperate(roleIdList);
        List<Long> operatorIdList = new ArrayList<Long>();

        for(SysMenuOperate o : operatorList){
            operatorIdList.add(o.getId());
        }
        roleResult.setOperators(operatorIdList);

        return ResultMsg.success(roleResult);
    }

    @Override
    @ServiceHandler(memo = "分页查询角色")
    public ResultMsg<SysRolePageResult> pageQuery(SysRolePageOrder order) {
        if (order.getPageNum() != null && order.getPageSize() != null) {
            PageHelper.startPage(order.getPageNum(), order.getPageSize());
        }
        List<SysRole> sysRoles = sysRoleMapper.pageQuery(order);
        PageInfo<SysRole> pageInfo = new PageInfo<SysRole>(sysRoles);
        SysRolePageResult rolePageResult = new SysRolePageResult();
        rolePageResult.setPageInfo(pageInfo);
        return ResultMsg.success(rolePageResult);
    }

    @Override
    @ServiceHandler(memo = "查询角色菜单所有操作权限ID")
    public ResultMsg<SysRoleMenuOperateAuthResult> findRoleMenuOperateAuth(BaseIdOrder order) {

        List<SysRoleAuth> roleAuthList = sysRoleAuthMapper.querySysRoleAuthByRoleId(order.getId());
        List<Long> list = new ArrayList<Long>();
        for (SysRoleAuth roleAuth : roleAuthList){
            list.add(roleAuth.getOperatorId());
        }
        SysRoleMenuOperateAuthResult result = new SysRoleMenuOperateAuthResult();
        result.setRoleId(order.getId());
        result.setOperateIds(list);
        return ResultMsg.success(result);
    }

    @ServiceHandler(memo = "--查询角色菜单操作权限--")
    public List<RoleMenuOperateAuthInfo> queryRoleMenuOperateAuth(BaseIdOrder order) {
        List<SysMenu> menus = sysMenuMapper.queryAllSysMenu();
        Map<Long, List<SysMenuOperate>> allMenuOperateMap = findAllMenuOperate();
        Map<Long, SysRoleAuth> roleAuthMap = findRoleAuth(order.getId());
        List<RoleMenuOperateAuthInfo> menuOperateAuthInfos = new ArrayList<RoleMenuOperateAuthInfo>();
        RoleMenuOperateAuthInfo roleMenuOperateAuthInfo = null;
        List<MenuOperateInfo> menuOperateInfoList = null;
        MenuOperateInfo menuOperateInfo = null;
        for (SysMenu menu : menus){
            roleMenuOperateAuthInfo = new RoleMenuOperateAuthInfo();
            roleMenuOperateAuthInfo.setMenuId(menu.getId());
            roleMenuOperateAuthInfo.setMenuName(menu.getMenuName());
            roleMenuOperateAuthInfo.setMenuCode(menu.getCode());
            menuOperateInfoList = new ArrayList<MenuOperateInfo>();
            List<SysMenuOperate> menuOperateList = allMenuOperateMap.get(menu.getId());
            if(menuOperateList == null){
                continue;
            }
            for (SysMenuOperate menuOperate : menuOperateList){
                menuOperateInfo = new MenuOperateInfo();
                menuOperateInfo.setId(menuOperate.getId());
                menuOperateInfo.setOperateName(menuOperate.getOperateName());
                menuOperateInfo.setCode(menuOperate.getCode());
                menuOperateInfo.setOperateUrl(menuOperate.getOperateUrl());
                if(roleAuthMap.get(menuOperateInfo.getId()) == null){
                    menuOperateInfo.setHasAuth(false);
                }else {
                    menuOperateInfo.setHasAuth(true);
                }
                menuOperateInfoList.add(menuOperateInfo);
            }
            roleMenuOperateAuthInfo.setMenuOperateList(menuOperateInfoList);
            menuOperateAuthInfos.add(roleMenuOperateAuthInfo);
        }
        return menuOperateAuthInfos;
    }

    @Override
    @ServiceHandler(memo = "保存角色权限", isTransaction = true)
    public ResultMsg saveRoleAuth(SysRoleAuthOrder order) {
        sysRoleAuthMapper.deleteSysRoleAuthByRoleId(order.getRoleId());
        List<Long> operateIds = order.getOperators();
        if(operateIds.size() == 0){
            return new ResultMsg();
        }
        List<SysMenuOperate> sysMenuOperates = sysMenuOperateMapper.selectBatchIds(operateIds);
        List<SysRoleAuth> sysRoleAuthList = new ArrayList<SysRoleAuth>();
        for (SysMenuOperate operate : sysMenuOperates){
            SysRoleAuth roleAuth = new SysRoleAuth();
            roleAuth.setRoleId(order.getRoleId());
            roleAuth.setMenuId(operate.getMenuId());
            roleAuth.setOperatorId(operate.getId());
            roleAuth.setCreateUserId(UserLoginUtils.getCurrentUser().getId());
            roleAuth.setUpdateUserId(UserLoginUtils.getCurrentUser().getId());
            roleAuth.setCreateTime(DateUtils.now());
            roleAuth.setUpdateTime(DateUtils.now());
            sysRoleAuthList.add(roleAuth);
        }
        sysRoleAuthMapper.insertBatch(sysRoleAuthList);
        return new ResultMsg();
    }

    @ServiceHandler(memo = "查询所有菜单操作")
    private Map<Long,List<SysMenuOperate>> findAllMenuOperate(){
        List<SysMenuOperate> sysMenuOperates = sysMenuOperateMapper.queryAllMenuOperate();
        Map<Long,List<SysMenuOperate>> menuOperateMap = new HashMap<Long,List<SysMenuOperate>>(HashMapSizeConstant.HASH_MAP_SIZE);
        List<SysMenuOperate> menuOperateListTemp = null;
        for (SysMenuOperate menuOperate : sysMenuOperates){
        	menuOperateListTemp = menuOperateMap.get(menuOperate.getMenuId());
            if(menuOperateListTemp == null){
            	menuOperateListTemp = new ArrayList<SysMenuOperate>();
            }
            menuOperateListTemp.add(menuOperate);
            menuOperateMap.put(menuOperate.getMenuId(),menuOperateListTemp);
        }
        return menuOperateMap;
    }

    @ServiceHandler(memo = "查询角色所有操作权限")
    private Map<Long, SysRoleAuth> findRoleAuth(Long roleId){
        List<SysRoleAuth> sysRoleAuth = sysRoleAuthMapper.querySysRoleAuthByRoleId(roleId);
        Map<Long, SysRoleAuth> roleAuthMap = new HashMap<Long, SysRoleAuth>(HashMapSizeConstant.HASH_MAP_SIZE);
        for (SysRoleAuth roleAuth : sysRoleAuth){
            roleAuthMap.put(roleAuth.getOperatorId(),roleAuth);
        }
        return roleAuthMap;
    }

}
